package com.main.ok.util;

/**
 * Project: greenline-epay-open-service-war
 * 
 * File Created at 2013-6-14
 * 
 * Copyright 2012 Greenline.com Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Greenline Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Greenline.com.
 */

import java.io.File;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Random;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.cxf.resource.URIResolver;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
//import org.eclipse.jetty.http.MimeTypes;
import org.springframework.http.MediaType;

import com.greenline.common.util.MD5Util;


/**
 * @Type Client
 * @Desc 模拟发送http请求基类
 * @author guoqing.fu
 * @date 2013-6-14
 * @Version V1.0
 */
public class Client {

    // 请求固定头参数
    public static String TerminalId = "WHTONGJI0199990007";
    public static String WK = "pI3PVNdQgbsbygmW";
    public static String PIK = "EAF106EA7AFDEE6FEAF106EA7AFDEE6F";

    public static String TransId = "";

    private static String Operator = "system";

    public static String SERVER = "http://localhost:8080/epay/rest/";

    /**
     * xml 格式发送请求
     * 
     * @param url
     * @param xmlfilePath
     * @return
     * @throws Exception
     */
    public void post(String url, String xmlfilePath) {
        String inputFile = this.getClass().getResource(xmlfilePath).getFile();
        URIResolver resolver;
        try {
            resolver = new URIResolver(inputFile);
            File input = new File(resolver.getURI());
//            HttpEntity entity = new FileEntity(input, ContentType.create(MimeTypes.TEXT_XML_UTF_8));
//            post(entity, url);
        } catch (IOException e) {
            System.out.println("发送请求失败！");
            System.out.println(e);
        }
    }

    /**
     * 根据对象post 请求
     * 
     * @param url
     * @param t
     * @param classiz
     */
    public final <T> void post(String url, T t, Class<T> classiz) {
        String xml = XmlConverter.toXML(t, classiz);
        HttpEntity entity = new StringEntity(xml, ContentType.create(MediaType.TEXT_XML_VALUE, "utf8"));
        post(entity, url);
    }

    private void post(HttpEntity entity, String url) {
        // TODO: 修改为自己的提交地址
        HttpPost post = new HttpPost(SERVER + url);

        HttpClient httpclient = new DefaultHttpClient();
        try {

            httpclient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 600000);
            httpclient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 600000);
            setHttps(httpclient);
            post.setEntity(entity);
            // 添加头
            addHeaders(post);
            HttpResponse response = httpclient.execute(post);
            // 对处理结果输出
            handleResponseContent(response);
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            post.releaseConnection();
            httpclient.getConnectionManager().shutdown();

        }

    }

    private void addHeaders(HttpPost post) {
        Random random = new Random();
        String reqSerialNo = Math.abs(random.nextInt()) + "";
        // post.addRequestHeader("Accept", MediaType.APPLICATION_JSON);
        post.addHeader("Accept", "text/xml");
        post.addHeader("Content-Type", "text/xml;charset=UTF-8");
        post.addHeader("terminalId", TerminalId);
        post.addHeader("operator", Operator);
        post.addHeader("reqSerialNo", reqSerialNo);
        post.addHeader("sign", getSign(post));
    }

    private void handleResponseContent(HttpResponse response) {
        String retSign = "";
        ByteArrayOutputStream os2 = new ByteArrayOutputStream();
        try {
            String returnSign = "";
            Header[] heads = response.getAllHeaders();
            for (int i = 0; i < heads.length; i++) {
                if (heads[i].getName().equals("sign")) {
                    returnSign = heads[i].getValue();
                    System.out.println(returnSign);
                }
            }
            response.getEntity().writeTo(os2);
            // 验证签名
            String content = os2.toString("utf8");
            retSign = MD5Util.getMD5Format(new String[] { WK, content });

//            if (!retSign.equals(returnSign)) {
//                System.err.println("returnSign");
//                System.err.println(returnSign);
//                System.err.println("retSign fail ！");
//            }
//            System.out.println("response Sign \n" + retSign + "\n");
//            System.err.println("response content \n" + content + "\n----end----\n\n\n");
            TransId = getTransIdbyResponse(content);
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    private String getSign(HttpPost post) {
        String sign = "";
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            post.getEntity().writeTo(os);
            String content = os.toString("utf8");
            sign = MD5Util.getMD5Format(new String[] { WK, content });
            System.out.println("request Sign \n" + sign + "\n");
            System.out.println("request content\n" + content + "\n");
        } catch (IOException e) {
            System.out.println("签名失败！");
            System.out.println(e);
            return null;
        }
        return sign;
    }

    /**
     * https
     * 
     * @param httpclient
     * @throws Exception
     */
    public static void setHttps(HttpClient httpclient) throws Exception {

        SSLContext ctx = SSLContext.getInstance("TLS");

        X509TrustManager tm = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        ctx.init(null, new TrustManager[] { tm }, null);
        // 不验证域名
        SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        Scheme sch = new Scheme("https", 443, ssf);
        httpclient.getConnectionManager().getSchemeRegistry().register(sch);
    }

    /**
     * 根据变量获得密码密文
     * 
     * @param pwd 密码明文
     * @param accountNo 卡号
     * @param pik 该终端的pik
     * @return
     */

    /**
     * @return the terminalId
     */
    public static String getTerminalId() {
        return TerminalId;
    }

    /**
     * @param terminalId the terminalId to set
     */
    public static void setTerminalId(String terminalId) {
        TerminalId = terminalId;
    }

    /**
     * @return the wK
     */
    public static String getWK() {
        return WK;
    }

    /**
     * @param wK the wK to set
     */
    public static void setWK(String wK) {
        WK = wK;
    }

    /**
     * @return the pIK
     */
    public static String getPIK() {
        return PIK;
    }

    /**
     * @param pIK the pIK to set
     */
    public static void setPIK(String pIK) {
        PIK = pIK;
    }

    /**
     * @return the sERVER
     */
    public static String getSERVER() {
        return SERVER;
    }

    /**
     * @param sERVER the sERVER to set
     */
    public static void setSERVER(String sERVER) {
        SERVER = sERVER;
    }

    /**
     * 根据返回内容截取流水id
     * 
     * @param content
     * @return
     */
    public static String getTransIdbyResponse(String content) {
        if (!content.contains("<transId>")) {
            return null;
        }
        int start = content.indexOf("<transId>") + "<transId>".length();
        int end = content.indexOf("</transId>");
        String transId = content.substring(start, end);
        return transId;

    }
}
